#pragma once

/**
 * @file snapshot_synthesizer.h
 * @brief 快照合成器定义
 * @details 定义了负责合成和发布限价订单簿快照的快照合成器
 */

#include "common/types.h"
#include "common/thread_utils.h"
#include "common/lf_queue.h"
#include "common/macros.h"
#include "common/mcast_socket.h"
#include "common/mem_pool.h"
#include "common/logging.h"

#include "market_data/market_update.h"
#include "matcher/me_order.h"

using namespace Common;

namespace Exchange {
  /**
   * @namespace Exchange
   * @brief 交易所相关功能的命名空间
   */
  /**
   * @class SnapshotSynthesizer
   * @brief 快照合成器类
   * @details 负责处理增量市场数据更新，维护限价订单簿快照，并定期发布完整快照
   */
  class SnapshotSynthesizer {
  public:
    /**
     * @brief 构造函数
     * @param market_updates 市场数据发布器提供的增量市场数据更新队列
     * @param iface 网络接口名称
     * @param snapshot_ip 快照数据多播IP地址
     * @param snapshot_port 快照数据多播端口
     */
    SnapshotSynthesizer(MDPMarketUpdateLFQueue *market_updates, const std::string &iface,
                        const std::string &snapshot_ip, int snapshot_port);

    /**
     * @brief 析构函数
     * @details 停止快照合成器线程并释放资源
     */
    ~SnapshotSynthesizer();

    /**
     * @brief 启动和停止快照合成器线程
     */
    /**
     * @brief 启动快照合成器线程
     */
    auto start() -> void;

    /**
     * @brief 停止快照合成器线程
     */
    auto stop() -> void;

    /**
     * @brief 处理增量市场数据更新并更新限价订单簿快照
     * @param market_update 要处理的市场数据更新
     */
    auto addToSnapshot(const MDPMarketUpdate *market_update);

    /**
     * @brief 在快照多播流上发布完整的快照周期
     * @details 发布包含开始标记、清除指令、所有活跃订单和结束标记的完整快照
     */
    auto publishSnapshot();

    /**
     * @brief 线程主方法
     * @details 处理来自市场数据发布器的增量更新，更新快照并定期发布快照
     */
    auto run() -> void;

    /**
     * @brief 删除的构造函数和赋值运算符
     * @details 禁用默认构造函数、拷贝构造函数、移动构造函数和对应的赋值运算符
     */
    SnapshotSynthesizer() = delete;

    SnapshotSynthesizer(const SnapshotSynthesizer &) = delete;

    SnapshotSynthesizer(const SnapshotSynthesizer &&) = delete;

    SnapshotSynthesizer &operator=(const SnapshotSynthesizer &) = delete;

    SnapshotSynthesizer &operator=(const SnapshotSynthesizer &&) = delete;

  private:
    /**
     * @brief 来自市场数据发布器的增量市场数据更新的无锁队列
     * @details 用于接收市场数据发布器转发的增量市场数据更新
     */
    MDPMarketUpdateLFQueue *snapshot_md_updates_ = nullptr;

    Logger logger_; /**< 日志记录器 */

    volatile bool run_ = false; /**< 线程运行标志 */

    std::string time_str_; /**< 时间字符串缓存，用于日志记录 */

    /**
     * @brief 快照多播流的多播套接字
     * @details 用于发布限价订单簿快照
     */
    McastSocket snapshot_socket_;

    /**
     * @brief 从证券ID到完整限价订单簿快照的映射
     * @details 存储每个证券的所有活跃订单信息，用于生成快照
     */
    std::array<std::array<MEMarketUpdate *, ME_MAX_ORDER_IDS>, ME_MAX_TICKERS> ticker_orders_;
    size_t last_inc_seq_num_ = 0; /**< 最后处理的增量市场数据更新序列号 */
    Nanos last_snapshot_time_ = 0; /**< 上次发布快照的时间戳（纳秒） */

    /**
     * @brief 管理快照限价订单簿中订单的MEMarketUpdate消息的内存池
     * @details 用于高效分配和回收市场数据更新对象的内存
     */
    MemPool<MEMarketUpdate> order_pool_;
  };
}
